name: Datapath BPF Complexity (ci-verifier)

# Any change in triggers needs to be reflected in the concurrency group.
on:
  workflow_dispatch:
    inputs:
      PR-number:
        description: "Pull request number."
        required: true
      context-ref:
        description: "Context in which the workflow runs. If PR is from a fork, will be the PR target branch (general case). If PR is NOT from a fork, will be the PR branch itself (this allows committers to test changes to workflows directly from PRs)."
        required: true
      SHA:
        description: "SHA under test (head of the PR branch)."
        required: true
      extra-args:
        description: "[JSON object] Arbitrary arguments passed from the trigger comment via regex capture group. Parse with 'fromJson(inputs.extra-args).argName' in workflow."
        required: false
        default: '{}'
  # Run every 6 hours
  schedule:
    - cron:  '0 5/6 * * *'

# By specifying the access of one of the scopes, all of those that are not
# specified are set to 'none'.
permissions:
  # To be able to access the repository with actions/checkout
  contents: read
  # To allow retrieving information from the PR API
  pull-requests: read
  # To be able to set commit status
  statuses: write

concurrency:
  # Structure:
  # - Workflow name
  # - Event type
  # - A unique identifier depending on event type:
  #   - schedule: SHA
  #   - workflow_dispatch: PR number
  #
  # This structure ensures a unique concurrency group name is generated for each
  # type of testing, such that re-runs will cancel the previous run.
  group: |
    ${{ github.workflow }}
    ${{ github.event_name }}
    ${{
      (github.event_name == 'schedule' && github.sha) ||
      (github.event_name == 'workflow_dispatch' && github.event.inputs.PR-number)
    }}
  cancel-in-progress: true

env:
  check_url: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
  # renovate: datasource=golang-version depName=go
  go-version: 1.22.0

jobs:
  commit-status-start:
    name: Commit Status Start
    runs-on: ubuntu-latest
    steps:
      - name: Set initial commit status
        uses: myrotvorets/set-commit-status-action@38f3f27c7d52fb381273e95542f07f0fba301307 # v2.0.0
        with:
          sha: ${{ inputs.SHA || github.sha }}

  setup-and-test:
    runs-on: ubuntu-latest-4cores-16gb
    name: Setup & Test
    strategy:
      fail-fast: false
      matrix:
        include:
          # renovate: datasource=docker depName=quay.io/lvh-images/complexity-test
          - kernel: '5.4-20240215.093821'
            ci-kernel: '54'
          # renovate: datasource=docker depName=quay.io/lvh-images/complexity-test
          - kernel: 'rhel8-20240221.094422'
            ci-kernel: '54'
          # renovate: datasource=docker depName=quay.io/lvh-images/complexity-test
          - kernel: '5.10-20240215.093821'
            ci-kernel: '510'
          # renovate: datasource=docker depName=quay.io/lvh-images/complexity-test
          - kernel: '5.15-20240215.093821'
            ci-kernel: '510'
          # renovate: datasource=docker depName=quay.io/lvh-images/complexity-test
          - kernel: '6.1-20240215.093821'
            ci-kernel: '61'
          # renovate: datasource=docker depName=quay.io/lvh-images/complexity-test
          - kernel: 'bpf-next-20240215.093821'
            ci-kernel: 'netnext'
    timeout-minutes: 60
    steps:
      # Warning: since this is a privileged workflow, subsequent workflow job
      # steps must take care not to execute untrusted code.
      - name: Checkout pull request branch (NOT TRUSTED)
        uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
        with:
          ref: ${{ inputs.SHA || github.sha }}
          persist-credentials: false

      - name: Provision LVH VMs
        uses: cilium/little-vm-helper@9d758b756305e83718a51b792a5aeabd022a39ec # v0.0.16
        with:
          test-name: datapath-bpf-complexity
          image: 'complexity-test'
          image-version: ${{ matrix.kernel }}
          host-mount: ./
          cpu: 4
          install-dependencies: 'true'
          cmd: |
            for i in {1..5}; do curl "https://golang.org" > /dev/null 2>&1 && break || sleep 5; echo "Waiting for systemd-resolved to be ready..."; done

            git config --global --add safe.directory /host
            uname -a
            # The LVH image might ship with an arbitrary Go toolchain version,
            # install the same Go toolchain version as current HEAD.
            CGO_ENABLED=0 GOPROXY=direct GOSUMDB= go install golang.org/dl/go${{ env.go-version }}@latest
            go${{ env.go-version }} download

      - name: Run verifier tests
        uses: cilium/little-vm-helper@9d758b756305e83718a51b792a5aeabd022a39ec # v0.0.16
        with:
          provision: 'false'
          cmd: |
            cd /host/
            # Run with cgo disabled, LVH images don't ship with gcc.
            CGO_ENABLED=0 go${{ env.go-version }} test -v -parallel=1 ./test/verifier -cilium-base-path /host -ci-kernel-version ${{ matrix.ci-kernel }}

      - name: Fetch artifacts
        if: ${{ !success() }}
        uses: cilium/little-vm-helper@9d758b756305e83718a51b792a5aeabd022a39ec # v0.0.16
        with:
          provision: 'false'
          cmd: |
            cd /host
            mkdir datapath-verifier
            find test/verifier \( -name "*.log" -o -name "*.o" \) -exec cp -v {} datapath-verifier/ \;

      - name: Upload artifacts
        if: ${{ !success() }}
        uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
        with:
          name: datapath-verifier_${{ matrix.kernel }}
          path: datapath-verifier
          retention-days: 5

  commit-status-final:
    if: ${{ always() }}
    name: Commit Status Final
    needs: setup-and-test
    runs-on: ubuntu-latest
    steps:
      - name: Set final commit status
        uses: myrotvorets/set-commit-status-action@38f3f27c7d52fb381273e95542f07f0fba301307 # v2.0.0
        with:
          sha: ${{ inputs.SHA || github.sha }}
          status: ${{ needs.setup-and-test.result }}
